package service

import (
	"server/global"
	"server/model/databases"
	"server/utils"

	"github.com/gin-gonic/gin"
	"github.com/gofrs/uuid"
	"go.uber.org/zap"
)

type JwtService struct {
}

// SetRedisJWT 将RefreshToken jwt存储到redis中
func (j *JwtService) SetRedisJWT(ctx *gin.Context, jwt string, uuid uuid.UUID) error {
	exp, err := utils.ParseDuration(global.Config.Jwt.RefreshTokenExpiryTime)
	if err != nil {
		return err
	}
	return global.Redis.Set(ctx, uuid.String(), jwt, exp).Err()
}

// GetRedisJWT 从redis中获取RefreshToken
func (j *JwtService) GetRedisJWT(ctx *gin.Context, uuid uuid.UUID) (string, error) {
	return global.Redis.Get(ctx, uuid.String()).Result()
}

// JoinInBlacklist 将 jwt 加入黑名单中
func (j *JwtService) JoinInBlacklist(jwtList databases.JwtBlacklist) error {
	if err := global.DB.Create(&jwtList).Error; err != nil {
		return err
	}
	// 添加到本地缓存中
	global.BlackCache.SetDefault(jwtList.Jwt, struct{}{})
	return nil
}

// IsInBlacklist 检查JWT是否在黑名单中
func (j *JwtService) IsInBlacklist(jwt string) bool {
	// 从黑名单缓存中检查JWT是否存在
	_, ok := global.BlackCache.Get(jwt)
	return ok
}

// LoadAll 从数据库加载所有的JWT黑名单并加入缓存
func LoadAll() {
	var data []string
	// 从数据库中获取所有的黑名单JWT
	if err := global.DB.Model(&databases.JwtBlacklist{}).Pluck("jwt", &data).Error; err != nil {
		global.Log.Error("Failed to load JWT blacklist from the database", zap.Error(err))
		return
	}
	for i := 0; i < len(data); i++ {
		global.BlackCache.SetDefault(data[i], struct{}{})
	}
}
